package com.wholesale.commons;

import java.util.ArrayList;
import java.util.HashMap;

import com.wholesale.GoodsDetailLayout;
import com.wholesale.beans.GoodsInfo;
import com.wholesale.utils.AsyncImageLoader;
import com.wholesale.utils.Constants;
import com.wholesale.utils.AsyncImageLoader.ImageCallback;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;

public class MyGrally extends View implements OnGestureListener {

	// 图片
	// private ArrayList<Bitmap> bitmapList = new ArrayList<Bitmap>();

	private HashMap<String, Bitmap> bitmapList = new HashMap<String, Bitmap>();

	private ArrayList<GoodsInfo> newGoodsInfo;
	private AsyncImageLoader imageLoader;
	// 当前图片的x坐标
	public int OffsetX = 0;
	// 当前图片的y坐标
	public int OffsetY = 0;

	// 当前图片的位置
	public static int postion = 0;

	private GestureDetector myGesture;

	// 初始旋转角度
	private final float fromDegrees = -10;
	// 结束旋转角度
	private final float toDegrees = 10;
	// 当前旋转角度
	private float curDegrees = -10;

	private Context context;
	private Bitmap preBitmap = null;
	private Bitmap curBitmap = null;
	private Bitmap next1Bitmap = null;
	private Bitmap next2Bitmap = null;
	private Bitmap next3Bitmap = null;

	private Bitmap preBitmapTemp = null;
	private Bitmap curBitmapTemp = null;
	private Bitmap next1BitmapTemp = null;
	private Bitmap next2BitmapTemp = null;
	private Bitmap next3BitmapTemp = null;

	// 图片与图片之间的间距
	private int bt = 5;
	// view的默认宽度
	public static int SCREEN_WIDTH = 320;
	// view的默认高度
	public static int SCREEN_HEIGHT = 480;

	private static int image_width = 220;
	private static int image_height = 330;

	private int initX = 80;
	private int initY = 10;

	private int preX = 20;

	// 标记为可以切换到下一张
	boolean flag = false;
	// 标记为需要向右滑动
	boolean flag1 = false;
	// 标记为需要向左滑动
	boolean flag2 = false;

	// // 移动方向 false向左，true向右
	boolean flag3 = false;
	float temp;

	private OnClickCallBack onClickCallBack;

	public MyGrally(Context context) {
		super(context);
		this.context = context;
		myGesture = new GestureDetector(context, this);
		setLongClickable(true);
		imageLoader = AsyncImageLoader.getInstance();
	}

	public MyGrally(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		myGesture = new GestureDetector(context, this);
		setLongClickable(true);
		imageLoader = AsyncImageLoader.getInstance();
	}

	public void setScreenWH(int w, int h) {
		this.SCREEN_WIDTH = w;
		this.SCREEN_HEIGHT = h;
		initX = w * initX / 320;
	}

	public void setGoodsInfo(ArrayList<GoodsInfo> newGoodsInfo) {
		this.newGoodsInfo = newGoodsInfo;
		for (GoodsInfo goods : newGoodsInfo) {
			if (bitmapList.get(goods.getGoodsThumb()) == null) {
				imageLoader.loadDrawable(goods.getGoodsThumb(),
						new ImageCallback() {
							@Override
							public void imageLoaded(Drawable imageDrawable,
									String imageUrl) {
								bitmapList.put(imageUrl, Constants
										.drawableToBitmap(imageDrawable));
							}
						});
			}
		}
	}

	public void setOnClickCallBack(OnClickCallBack onClickCallBack) {
		this.onClickCallBack = onClickCallBack;
	}

	/**
	 * 添加图片
	 * 
	 * @param bitmap
	 */
	public void addBitmap(String url, Bitmap bitmap) {
		bitmapList.put(url, bitmap);
	}

	/**
	 * 获取当前图片的位置
	 * 
	 * @return int
	 */
	public int getPostion() {
		return postion;
	}

	// 重写画布方法
	@Override
	public void draw(Canvas canvas) {
		Paint p = new Paint();
		if (!flag3) { // 向左滑动
			if (preBitmap != null) {
				canvas.drawBitmap(preBitmapTemp, (float) (-SCREEN_WIDTH * 0.8
						+ initX - 2 * bt), initY + 2 * bt, p);
			}
		}

		if (next3Bitmap != null) {
			canvas.drawBitmap(next3BitmapTemp, initX + 5 * 2 * bt, initY + 5
					* bt, p);
		}
		if (next2Bitmap != null) {
			canvas.drawBitmap(next2BitmapTemp, initX + 3 * 2 * bt, initY + 4
					* bt, p);
		}
		if (next1Bitmap != null) {
			canvas.drawBitmap(next1BitmapTemp, initX + 1 * 2 * bt, initY + 3
					* bt, p);
		}
		if (!flag3) { // 向左滑动
			if (curBitmap != null) {
				canvas.drawBitmap(curBitmapTemp,
						(float) (OffsetX * 0.8 + initX - 2 * bt), initY + 2
								* bt, p);
			}
		} else {
			if (curBitmap != null) {
				canvas.drawBitmap(curBitmapTemp, (float) (initX - 2 * bt),
						initY + 2 * bt, p);
			}
		}
		if (flag3) { // 向右滑动
			if (preBitmap != null) {
				canvas.drawBitmap(
						preBitmapTemp,
						(float) ((OffsetX - SCREEN_WIDTH) * 0.8 + initX - 2 * bt),
						initY + 2 * bt, p);
			}
		}
	}

	private Bitmap createBitmap() {
		Bitmap bit = Bitmap.createBitmap(SCREEN_WIDTH, SCREEN_HEIGHT,
				Config.RGB_565);
		Canvas canvas = new Canvas(bit);
		canvas.save();
		canvas.drawColor(Color.GRAY);
		canvas.restore();
		return bit;
	}

	public void setPostion(int postion) {
		this.postion = postion;
		OffsetX = 0;
		OffsetY = 0;
		// 是否bitmap内存
		if (null != preBitmap) {
			preBitmap.recycle();
			preBitmapTemp.recycle();
		}
		if (null != curBitmap) {
			curBitmap.recycle();
			curBitmapTemp.recycle();
		}
		if (null != next1Bitmap) {
			next1Bitmap.recycle();
			next1BitmapTemp.recycle();
		}
		if (null != next2Bitmap) {
			next2Bitmap.recycle();
			next2BitmapTemp.recycle();
		}
		if (null != next3Bitmap) {
			next3Bitmap.recycle();
			next3BitmapTemp.recycle();
		}
		// int size = bitmapList.size();
		// if (postion > 0) {
		// preBitmap = bitmapList.get(postion - 1);
		// if (preBitmap == null) {
		// preBitmap = createBitmap();
		// }
		// preBitmap = zoomBitmap(preBitmap,0);
		// preBitmapTemp = getBitmap(preBitmap, toDegrees, 0);
		// } else {
		// preBitmap = null;
		// }
		// if (postion < size) {
		// curBitmap = bitmapList.get(postion);
		// if (curBitmap == null) {
		// curBitmap = createBitmap();
		// }
		// curBitmap = zoomBitmap(curBitmap,0);
		// curBitmapTemp = getBitmap(curBitmap, fromDegrees, 0);
		// }
		// if ((postion + 1) < size) {
		// next1Bitmap = bitmapList.get(postion + 1);
		// if (next1Bitmap == null) {
		// next1Bitmap = createBitmap();
		// }
		// next1Bitmap = zoomBitmap(next1Bitmap,1);
		// next1BitmapTemp = getBitmap(next1Bitmap, fromDegrees, 1);
		// } else {
		// next1Bitmap = null;
		// }
		// if ((postion + 2) < size) {
		// next2Bitmap = bitmapList.get(postion + 2);
		// if (next2Bitmap == null) {
		// next2Bitmap = createBitmap();
		// }
		// next2Bitmap = zoomBitmap(next2Bitmap,2);
		// next2BitmapTemp = getBitmap(next2Bitmap, fromDegrees, 2);
		// } else {
		// next2Bitmap = null;
		// }
		// if ((postion + 3) < size) {
		// next3Bitmap = bitmapList.get(postion + 3);
		// if (next3Bitmap == null) {
		// next3Bitmap = createBitmap();
		// }
		// next3Bitmap = zoomBitmap(next3Bitmap,3);
		// next3BitmapTemp = getBitmap(next3Bitmap, fromDegrees, 3);
		// } else {
		// next3Bitmap = null;
		// }

		int size = newGoodsInfo.size();
		if (postion > 0) {
			preBitmap = bitmapList.get(newGoodsInfo.get(postion - 1)
					.getGoodsThumb());
			if (preBitmap == null) {
				preBitmap = createBitmap();
			}
			preBitmap = zoomBitmap(preBitmap, 0);
			preBitmapTemp = getBitmap(preBitmap, toDegrees, 0);
		} else {
			preBitmap = null;
		}
		if (postion < size) {
			curBitmap = bitmapList.get(newGoodsInfo.get(postion)
					.getGoodsThumb());
			if (curBitmap == null) {
				curBitmap = createBitmap();
			}
			curBitmap = zoomBitmap(curBitmap, 0);
			curBitmapTemp = getBitmap(curBitmap, fromDegrees, 0);
		}
		if ((postion + 1) < size) {
			next1Bitmap = bitmapList.get(newGoodsInfo.get(postion + 1)
					.getGoodsThumb());
			if (next1Bitmap == null) {
				next1Bitmap = createBitmap();
			}
			next1Bitmap = zoomBitmap(next1Bitmap, 1);
			next1BitmapTemp = getBitmap(next1Bitmap, fromDegrees, 1);
		} else {
			next1Bitmap = null;
		}
		if ((postion + 2) < size) {
			next2Bitmap = bitmapList.get(newGoodsInfo.get(postion + 2)
					.getGoodsThumb());
			if (next2Bitmap == null) {
				next2Bitmap = createBitmap();
			}
			next2Bitmap = zoomBitmap(next2Bitmap, 2);
			next2BitmapTemp = getBitmap(next2Bitmap, fromDegrees, 2);
		} else {
			next2Bitmap = null;
		}
		if ((postion + 3) < size) {
			next3Bitmap = bitmapList.get(newGoodsInfo.get(postion + 3)
					.getGoodsThumb());
			if (next3Bitmap == null) {
				next3Bitmap = createBitmap();
			}
			next3Bitmap = zoomBitmap(next3Bitmap, 3);
			next3BitmapTemp = getBitmap(next3Bitmap, fromDegrees, 3);
		} else {
			next3Bitmap = null;
		}
	}

	private Bitmap wheelBitmap(final Bitmap bitmap, float angle) {
		int center = ((int) ((float) image_width / 320 * SCREEN_WIDTH)) / 2;
		Camera mCamera = new Camera();
		mCamera.save();
		mCamera.rotateY(angle);
		Matrix mMatrix = new Matrix();
		mCamera.getMatrix(mMatrix);
		mMatrix.preTranslate(-center, -center);
		mMatrix.postTranslate(center, center);
		mCamera.restore();
		return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
				bitmap.getHeight(), mMatrix, true);
	}

	private Bitmap getBitmap(final Bitmap bitmap, float angle, int index) {
		int center = ((int) ((float) image_width / 320 * SCREEN_WIDTH)) / 2;

		Camera mCamera = new Camera();
		mCamera.save();
		mCamera.rotateY(angle);
		Matrix mMatrix = new Matrix();
		mCamera.getMatrix(mMatrix);
		mMatrix.preTranslate(-center, -center);
		mMatrix.postTranslate(center, center);
		mCamera.restore();
		// Bitmap temp = zoomBitmap(bitmap, index);
		// Bitmap newBitmap = Bitmap.createBitmap(temp, 0, 0, temp.getWidth(),
		// temp.getHeight(), mMatrix, true);
		System.gc();
		Bitmap newBitmap = null;
		try {
			newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
					bitmap.getHeight(), mMatrix, true);

		} catch (OutOfMemoryError e) {
			// 提示系统，进行内存回收
			System.gc();
			 
			newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
					bitmap.getHeight(), mMatrix, true);
			

		}

		return newBitmap;
	}

	public Bitmap zoomBitmap(Bitmap bitmap, int index) {
		int w = (int) ((float) image_width / 320 * SCREEN_WIDTH) - 2 * index
				* bt;
		int h = (int) ((float) image_height / 480 * SCREEN_HEIGHT) - 2 * index
				* bt;
		Paint mPaint = new Paint();
		mPaint.setColor(Color.RED);
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		Matrix matrix = new Matrix();
		float scaleWidth = ((float) (w - 4) / width);
		float scaleHeight = ((float) (h - 4) / height);
		matrix.postScale(scaleWidth, scaleHeight);
		Bitmap newBmp = Bitmap.createBitmap(w, h, Config.ARGB_8888);
		Canvas cv = new Canvas(newBmp);
		cv.drawRect(0, 0, w, h, mPaint);
		cv.drawBitmap(
				Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true),
				2, 2, null);
		cv.save();
		return newBmp;
	}

	public void onFling(int paramFloat1) {
		if (OffsetX > SCREEN_WIDTH / 3) {
			if (preBitmap != null) {
				flag = true;
				flag1 = true;
			}
		} else if (OffsetX < -SCREEN_WIDTH / 3) {
			if (next1Bitmap != null) {
				flag = true;
				flag2 = true;
			}
		}
		// 开始动画效果
		temp = curDegrees;
		startAnimation(new MyAnimation());
		invalidate();
	}

	public boolean setOnTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			if (postion > 0) {
				onFling(0);
			}
			break;
		}
		return myGesture.onTouchEvent(event);
	}

	public void handleScroll(int deltaX) {
		if (deltaX > 0) {
			OffsetX -= -deltaX;
		} else {
			OffsetX += deltaX;
		}
		invalidate();
	}

	class MyAnimation extends Animation {

		private int temp;

		@Override
		public void initialize(int width, int height, int parentWidth,
				int parentHeight) {
			temp = OffsetX;
			super.initialize(width, height, parentWidth, parentHeight);
			setDuration(300);
			setFillAfter(true);
			setInterpolator(new LinearInterpolator());
		}

		@Override
		protected void applyTransformation(float interpolatedTime,
				Transformation t) {
			if (flag3) {// 向右
				transformImageBitmap(preBitmap, t, interpolatedTime);
			} else {
				transformImageBitmap(curBitmap, t, interpolatedTime);
			}

			// if(OffsetX>-200){
			if (flag) {
				if (temp > 0) {
					OffsetX = (int) ((SCREEN_WIDTH - temp) * interpolatedTime + temp);
				} else {
					OffsetX = (int) ((-SCREEN_WIDTH - temp) * interpolatedTime + temp);
				}
				// 不需要变换的情况
			} else {
				OffsetX = (int) (temp * (1 - interpolatedTime));
			}
			invalidate();
			// }

		}
	}

	private void transformImageBitmap(Bitmap child, Transformation t,
			float interpolatedTime) {
		if (flag3) { // 向右滑动 角度从当前的到 -20
			if (flag) {
				curDegrees = temp + (fromDegrees - temp) * interpolatedTime;
			} else {
				curDegrees = temp + (-temp + toDegrees) * interpolatedTime;
			}
		} else { // 向左滑动 角度从当前的到 20
			if (flag) {
				curDegrees = temp + (-temp + toDegrees) * interpolatedTime;
			} else {
				curDegrees = temp + (fromDegrees - temp) * interpolatedTime;
			}
		}
		if (flag3) { // 向右
			preBitmapTemp = getBitmap(preBitmap, curDegrees, 0);
		} else {
			curBitmapTemp = getBitmap(curBitmap, curDegrees, 0);
		}

	}

	// 动画结束后需要做一些工作
	@Override
	protected void onAnimationEnd() {
		if (bitmapList.size() > 0) {
			if (flag1) {
				postion = postion - 1;
			} else if (flag2) {
				postion = postion + 1;
			}
			flag1 = false;
			flag2 = false;
			OffsetX = 0;
			setPostion(postion);
			curDegrees = fromDegrees;
			clearAnimation();
			flag = false;
		}
	}

	public boolean onDown(MotionEvent e) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		if (bitmapList.size() > 0) {
			if (postion > 0 || !flag3) {
				onFling((int) -velocityX);
			}
		}
		return true;
	}

	public void onLongPress(MotionEvent e) {
		if (onClickCallBack != null) {
			onClickCallBack.onClick(postion);
		}

	}

	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		float distance = e2.getX() - e1.getX();
		if (bitmapList.size() > 0) {
			if (postion > 0 || distance < 0) {
				int w = ((initX - 2 * bt + curBitmap.getWidth() - preX) / 2);
				if (distance > 0) {// 向右滑动
					flag3 = true;
					if (distance < w) { // 还没有滑动过半 角度从20 减到0
						curDegrees = (1 - distance / w) * toDegrees;
					} else { // 滑动过半角度从0到-20
						curDegrees = (distance / w - 1) * fromDegrees;
					}
				} else {// 向左滑动
					flag3 = false;
					if (-distance < w) { // 还没有滑动过半 角度从-20 减到0
						curDegrees = (1 + distance / w) * fromDegrees;
					} else { // 滑动过半角度从0到20
						curDegrees = -(distance / w + 1) * toDegrees;
					}
				}

				if (curDegrees > toDegrees) {
					curDegrees = toDegrees;
				} else if (curDegrees < fromDegrees) {
					curDegrees = fromDegrees;
				}
				if (flag3) { // 向右
					preBitmapTemp = getBitmap(preBitmap, curDegrees, 0);
					// preBitmapTemp = wheelBitmap(preBitmapTemp, curDegrees);
				} else {
					curBitmapTemp = getBitmap(curBitmap, curDegrees, 0);
					// curBitmapTemp = wheelBitmap(curBitmapTemp, curDegrees);
				}
				handleScroll(-1 * (int) distanceX);
			}
		}
		return true;
	}

	public void onShowPress(MotionEvent e) {

	}

	public boolean onSingleTapUp(MotionEvent e) {
		if (onClickCallBack != null) {
			onClickCallBack.onClick(postion);
		}
		return true;
	}

	/**
	 * 对外界开放的回调接口
	 * 
	 * @author hou jinghao
	 */
	public interface OnClickCallBack {
		// 注意 此方法是用来设置目标对象的图像资源
		public void onClick(int index);

		public void showLoading(boolean show);
	}
}
